<?php

// +----------------------------------------------------------------------
// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
// +----------------------------------------------------------------------
// | Copyright (c) 2013-2018 http://www.thinkcmf.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +---------------------------------------------------------------------
// | Author: Dean <zxxjjforever@163.com>
// +----------------------------------------------------------------------

namespace cmf\controller;

use think\Db;
use common\home\model\ThemeModel;
use think\Debug;
use think\View;
use common\user\service\LoginService as Login;
use common\wechat\service\ApiService as wx;
use think\Config;
use think\exception\HttpResponseException;

class HomeBaseController extends BaseController {

    public function _initialize() {
        //判断访问方式
//		if(!defined('IS_M') || (IS_M !== true)){
//            if((cmf_is_mobile()==true) || (cmf_is_wechat()==true) ) {
//                header("Location:" . '/m'.$this->request->url());
//                exit();
//			}
//		}

	
//        session('user',null);
        // 监听home_init
        hook('home_init');
        parent::_initialize();
        $siteInfo = cmf_get_site_info();
        View::share('site_info', $siteInfo);
        // 判断是否有第三方登录
        // 判断id是否存在
        $userId = cmf_get_current_user_id();

        if (!empty($userId)) {
            // 看是否有wx登录
            if (isset($sessionUser['wechat']) && is_array($sessionUser['wechat'])) {
                $wx = new wx;
                $wx_info = $wx->get_wx_info($sessionUser['wechat']['openid'], $this->request);
                $Login = new Login();
                $ret = $Login->doLogin($wx_info);
            }
        } else {
            // 微信端访问
            if (cmf_is_wechat()) {
                // 判断session
                $module = $this->request->module();
                $controller = $this->request->controller();
                $action = $this->request->action();
                $rule = $module . $controller . $action;
                $url = $this->request->url(true);

                $notRequire = ["wxIndexindex"];
                if (!in_array($rule, $notRequire)) {
                    // 检查是否已经授权过了
                    $sessionUser = session('user');

                    if (!isset($sessionUser['wechat']) || !is_array($sessionUser['wechat'])) {
                        // 对不在过滤列表内的做响应
                        // 判断是否已经有授权了.没有授权则要授权
                        // SDK实例对象
//                    $oauth = & load_wechat('Oauth');
                        $config = Config::get('wechat.Official');
                        $oauth = new \WeChat\Oauth($config);

                        // 认证授权网页
                        $redirect_url = url('wechat/index/index', '', FALSE, true);
                        $data = ['redirect' => urlencode($url)];
                        $state = base64_encode(json_encode($data));
                        $wx_snsapi = $this->request->param('wechat_snsapi', 0);

                        if (empty($wx_snsapi)) {
                            // 有默认的url必须是snsapi_userinfo (snsapi_base | snsapi_userinfo)
                            if (in_array($rule, config('wechat_snsapi_userinfo'))) {
                                $wx_snsapi = 'snsapi_userinfo';
                            } else {
                                $wx_snsapi = empty($wx_snsapi) ? 'snsapi_base' : $wx_snsapi;
                            }
                        }

//                    var_dump($redirect_url,$state,$wx_snsapi);exit;
                        // 执行接口操作
                        // 需要判断是否需要用户信息
                        // 默认不需要用户信息.如果需要用户信息.就加入特殊参数.和指定控制器访问,需要用户信息
                        $result = $oauth->getOauthRedirect($redirect_url, $state, $wx_snsapi);

                        // 处理返回结果
                        if ($result === FALSE) {
                            // 接口失败的处理
                            return false;
                        } else {
                            if (IS_SWOOLE) {
                                return $this->location($result);
                            } else {
                                header("Location:" . $result);
                                exit();
                            }
                            // 接口成功的处理
                        }
                    } else {
                        // 判断id是否存在
                        $userId = cmf_get_current_user_id();

                        if (empty($userId)) {
                            // 看是否有wx登录
                            if (isset($sessionUser['wechat']) && is_array($sessionUser['wechat'])) {
                                $wx = new wx;
                                $wx_info = $wx->get_wx_info($sessionUser['wechat']['openid'], $this->request);
                                $Login = new Login();
                                $ret = $Login->doLogin($wx_info);
                            }
                        }
                    }
                }
            }
        }
    }

    public function _initializeView() {
        $cmfThemePath = config('cmf_theme_path');
        $cmfDefaultTheme = cmf_get_current_theme();
        $cmfDefaultThemeDate = cmf_get_current_theme_date();
        $module = $this->request->module();
        $controller = $this->request->controller();
        $action = $this->request->action();
        $url = $this->request->url(true);
        $rule = "{$url},cn,10001,,10001,{$module},{$controller},{$action}";

        $themePath = "{$cmfThemePath}{$cmfDefaultTheme}";

        $root = cmf_get_root();
        $app_root = get_app_root();

        //使cdn设置生效
        $cdnSettings = cmf_get_option('cdn_settings');
        if (empty($cdnSettings['cdn_static_root'])) {
            $viewReplaceStr = [
                '__ROOT__' => $app_root,
                '__TMPL__' => "{$root}/{$themePath}",
                '__STATIC__' => "{$root}/static",
                '__WEB_ROOT__' => $root,
                '__THEME_DATE__' => $cmfDefaultThemeDate,
                '__RULE__' => $rule,
                '__MODULE__' => $module,
                '__CONTROLLER__' => $controller,
            ];
        } else {
            $cdnStaticRoot = rtrim($cdnSettings['cdn_static_root'], '/');
            $viewReplaceStr = [
                '__ROOT__' => $root,
                '__TMPL__' => "{$cdnStaticRoot}/{$themePath}",
                '__STATIC__' => "{$cdnStaticRoot}/static",
                '__WEB_ROOT__' => $cdnStaticRoot,
                '__THEME_DATE__' => $cmfDefaultThemeDate,
                '__RULE__' => $rule,
                '__MODULE__' => $module,
                '__CONTROLLER__' => $controller,
            ];
        }

        $viewReplaceStr = array_merge(config('view_replace_str'), $viewReplaceStr);
        config('template.view_base', "{$themePath}/");
        if (IS_SWOOLE) {
            // 为了区分模板载入路径.不同端进来后,会存在定位模板的问题.
            session('template.view_base_' . APP_NAME, "$themePath/");
        }
        config('view_replace_str', $viewReplaceStr);

        $themeErrorTmpl = "{$themePath}/error.html";
        if (file_exists_case($themeErrorTmpl)) {
            config('dispatch_error_tmpl', $themeErrorTmpl);
        }

        $themeSuccessTmpl = "{$themePath}/success.html";
        if (file_exists_case($themeSuccessTmpl)) {
            config('dispatch_success_tmpl', $themeSuccessTmpl);
        }
    }

    /**
     * 加载模板输出
     * @access protected
     * @param string $template 模板文件名
     * @param array $vars 模板输出变量
     * @param array $replace 模板替换
     * @param array $config 模板参数
     * @return mixed
     */
    protected function fetch($template = '', $vars = [], $replace = [], $config = []) {
        $template = $this->parseTemplate($template);


        //获取模板文件变量
        $more = $this->getThemeFileMore($template);
        $this->assign('theme_vars', $more['vars']);
        $this->assign('theme_widgets', $more['widgets']);
        $content = parent::fetch($template, $vars, $replace, $config);

        $designingTheme = session('admin_designing_theme');

        if ($designingTheme) {
            $app        = $this->request->module();
            $controller = $this->request->controller();
            $action     = $this->request->action();

            $output = <<<hello
<script>
var _themeDesign=true;
var _themeTest="test";
var _app='{$app}';
var _controller='{$controller}';
var _action='{$action}';
var _themeFile='{$more['file']}';
parent.simulatorRefresh();
</script>
hello;

            $pos = strripos($content, '</body>');
            if (false !== $pos) {
                $content = substr($content, 0, $pos) . $output . substr($content, $pos);
            } else {
                $content = $content . $output;
            }
        }


        return $content;
    }

    /**
     * 自动定位模板文件
     * @access private
     * @param string $template 模板文件规则
     * @return string
     */
    private function parseTemplate($template) {
        // 分析模板文件规则
        $request = $this->request;
        // 获取视图根目录
        if (strpos($template, '@')) {
            // 跨模块调用
            list($module, $template) = explode('@', $template);
        }

        if (IS_SWOOLE) {
            //利用访问时间判断是调用哪个模板
            /*
              if (isset($_SESSION['think']['template']["home_time"])) {
              $home_time = $_SESSION['think']['template']["home_time"];
              } else {
              $home_time = 0;
              }
              if (isset($_SESSION['think']['template']["admin_time"])) {
              $admin_time = $_SESSION['think']['template']["admin_time"];
              } else {
              $admin_time = 0;
              }

              if ($home_time != 0 || $admin_time != 0) {
              if ($admin_time > $home_time) {
              config('template.view_base', $_SESSION['think']['template']["view_base_admin"]);
              } else {

              config('template.view_base', $_SESSION['think']['template']["view_base"]);
              }
              }
             */
        }



        $viewBase = config('template.view_base');

        if ($viewBase) {
            // 基础视图目录
            $module = isset($module) ? $module : $request->module();
            $path = $viewBase . ($module ? $module . DS : '');
        } else {
            $path = isset($module) ? APP_PATH . $module . DS . 'view' . DS : config('template.view_path');
        }

        $depr = config('template.view_depr');
        if (0 !== strpos($template, '/')) {
            $template = str_replace(['/', ':'], $depr, $template);
            $controller = cmf_parse_name($request->controller());
            if ($controller) {
                if ('' == $template) {
                    // 如果模板文件名为空 按照默认规则定位
                    $template = str_replace('.', DS, $controller) . $depr . cmf_parse_name($request->action(true));
                } elseif (false === strpos($template, $depr)) {
                    $template = str_replace('.', DS, $controller) . $depr . $template;
                }
            }
        } else {
            $template = str_replace(['/', ':'], $depr, substr($template, 1));
        }
        return $path . ltrim($template, '/') . '.' . ltrim(config('template.view_suffix'), '.');
    }

    /**
     * 获取模板文件变量
     * @param string $file
     * @param string $theme
     * @return array
     */
    private function getThemeFileMore($file, $theme = "") {

        //TODO 增加缓存
        $theme = empty($theme) ? cmf_get_current_theme() : $theme;

        // 调试模式下自动更新模板
        if (APP_DEBUG) {
            $themeModel = new ThemeModel();
            $themeModel->updateTheme($theme);
        }

        $themePath = config('cmf_theme_path');

        $file = str_replace('\\', '/', $file);
        $file = str_replace('//', '/', $file);
        $themeFile = str_replace(['.html', '.php', $themePath . $theme . "/"], '', $file);


        $files = Db::name('theme_file')->field('more')->where(['theme' => $theme])->where(function ($query) use ($themeFile) {
            $query->where(['is_public' => 1])->whereOr(['file' => $themeFile]);
                })->select();

        $vars = [];
        $widgets = [];
        foreach ($files as $file) {
            $oldMore = json_decode($file['more'], true);
            if (!empty($oldMore['vars'])) {
                foreach ($oldMore['vars'] as $varName => $var) {
                    $vars[$varName] = $var['value'];
                }
            }

            if (!empty($oldMore['widgets'])) {
                foreach ($oldMore['widgets'] as $widgetName => $widget) {

                    $widgetVars = [];
                    if (!empty($widget['vars'])) {
                        foreach ($widget['vars'] as $varName => $var) {
                            $widgetVars[$varName] = $var['value'];
                        }
                    }

                    $widget['vars'] = $widgetVars;
                    $widgets[$widgetName] = $widget;
                }
            }
        }

        return ['vars' => $vars, 'widgets' => $widgets, 'file' => $themeFile];
    }

    public function checkUserLogin() {
        $userId = cmf_get_current_user_id();
        if (empty($userId)) {
            if ($this->request->isAjax()) {
                $this->error("您尚未登录", cmf_url("index/Login/index"));
            } else {
                $this->redirect(cmf_url("index/Login/index"));
            }
        }
    }

    /**
     * 创建静态页面
     * @access protected
     * @htmlfile 生成的静态文件名称
     * @htmlpath 生成的静态文件路径
     * @param string $templateFile 指定要调用的模板文件
     * 默认为空 由系统自动定位模板文件
     * @return string
     * return $this->buildHtml('index',SA_PUBLIC,':index');
     *
     */
    protected function buildHtml($htmlfile = '', $htmlpath = '', $templateFile = '', $vars = [], $replace = [], $config = []) {
        $content = $this->fetch($templateFile);
        $htmlpath = !empty($htmlpath) ? $htmlpath :SA_PUBLIC;
        $htmlfile = $htmlpath . $htmlfile . '.' . 'html';
        if (!is_file($htmlfile)) {
            $html = object_array($content)["*data"];
            $File = new \think\template\driver\File();
            $File->write($htmlfile, $html);
        }

        return $content;
    }


    /**
     * 操作错误返回信息
     * @access protected
     * @param mixed     $msg 提示信息,下面的参数无效用不了
     * @param string    $url 跳转的URL地址
     * @param mixed     $data 返回的数据
     * @param integer   $wait 跳转等待时间
     * @param array     $header 发送的Header信息
     * @return void
     * @todo 注意这里是继承了框架的方法,但和框架无关,只是为了继承同名方法，方便其他地方统一
     */
    protected function error($msg = '', $url = null, $data = '', $wait = 3, array $header = []) {
        /* 错误
          {
          "ret": 400,
          "data": [],
          "msg": "非法请求：服务Demo.None不存在"
          }
         */
        //需要识别出来是什么类型的错误
        //判断msg是不是数组是数组则返回某些标准错误返回格式
        $ret = [];
        if (is_numeric($msg)) {
            //从错误返回库里取错误编号返回
            $err = Config::get('code.code_err');
            if (isset($err[$msg])) {
                $ret['alert'] = $err[$msg];
            } else {
                $ret['alert'] = $msg;
            }
        } else {
            $ret['alert'] = $msg;
        }
        return self::ajaxReturn($ret, FALSE);
    }

    /**
     * 操作成功返回信息
     * @access protected
     * @param mixed     $msg 返回数据,下面的参数无效用不了
     * @param string    $url 跳转的URL地址
     * @param mixed     $data 返回的数据
     * @param integer   $wait 跳转等待时间
     * @param array     $header 发送的Header信息
     * @return void
     * @todo 注意这里是继承了框架的方法,但和框架无关,只是为了继承同名方法，方便其他地方统一
     */
    protected function success($msg = '', $url = null, $data = '', $wait = 3, array $header = []) {
        return self::ajaxReturn($msg);
    }

    /**
     * Ajax方式返回数据到客户端
     * @access protected
     * @param mixed $content 要返回的数据
     * @param boolean $state 有效or无效
     * @return void
     */
    protected function ajaxReturn($content, $state = true) {
        /* 正确
          {
          "ret": 200,
          "data": {
          "title": "Hello World!",
          "content": "PHPer您好，欢迎使用PhalApi！",
          "version": "1.2.0",
          "time": 1480776025
          },
          "msg": ""
          }
         */


        //有效返回无效返回
        $data['result'] = $state == true ? true : false;
        //返回详情
        $data['detail'] = $state == true ? $content : '';
        //定义错误消息
        $data['msg'] = is_array($content) && isset($content['alert']) ? $content['alert'] : '';
        //返回编号
        $data['code'] = intval($state);


        throw new HttpResponseException(json($data));
    }


}
